package com.qidianit.springboot.util;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 戴着假发的程序员
 * @company 起点编程
 * @date 2025/5/7 上午 9:46
 * @description
 **/

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ValueOperations<String, String> valueOperations;
    private static final String ORDER_KEY_PREFIX = "order:seq:"; // Redis Key 前缀
    private static final String BUSINESS_PREFIX = "ORD"; // 业务标识
//    @Autowired
//    private HashOperations<String, String, Object> hashOperations;
//    @Autowired
//    private ListOperations<String, Object> listOperations;
//    @Autowired
//    private SetOperations<String, Object> setOperations;
//    @Autowired
//    private ZSetOperations<String, Object> zSetOperations;

    /** 默认过期时长，单位：秒 */
    //public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
    /** 不设置过期时长 */
    public final static long NOT_EXPIRE = -1;

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    /**
     * 插入值-对象,指定数据库索引,指定过期时间
     *
     * @param key     键
     * @param value   值
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @param expire  过期时间 单位：秒
     */
    public void set(String key, Object value, Integer dbIndex, long expire) {
        // 选择数据库
        setDbIndex(dbIndex);
        valueOperations.set(key, JSON.toJSONString(value));
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    /**
     * 插入值-对象
     *
     * @param key     键
     * @param value   值
     * @param dbIndex 数据库索引 范围 0-15 默认0
     */
    public void set(String key, Object value, Integer dbIndex) {
        set(key, value, dbIndex, NOT_EXPIRE);
    }

    /**
     * 插入值-对象 ,默认0 index数据库
     *
     * @param key   键
     * @param value 值
     */
    public void set(String key, Object value) {
        set(key, value, 0, NOT_EXPIRE);
    }

    public void set(String key, String value) {
        valueOperations.set(key, JSON.toJSONString(value));
    }

    /**
     * 获取值-对象,指定数据库索引,并设置过期时间
     *
     * @param key     键
     * @param clazz   字节码对象
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @param expire  过期时间 单位：秒
     * @return
     */
    public <T> T get(String key, Class<T> clazz, Integer dbIndex, long expire) {
        setDbIndex(dbIndex);
        String value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value == null ? null : JSONObject.parseObject(JSON.toJSONString(value),clazz);
    }

    /**
     * 取值-对象 指定数据库索引
     *
     * @param key     键
     * @param clazz   字节码对象
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @return
     */
    public <T> T get(String key, Class<T> clazz, Integer dbIndex) {
        setDbIndex(dbIndex);
        String value = valueOperations.get(key);
        System.out.println(JSONObject.parseObject(value,clazz));
        return null;
    }

    /**
     * 取值-对象
     *
     * @param key   键
     * @param clazz 字节码对象
     * @return
     */
    public <T> T get(String key, Class<T> clazz) {
        return get(key, clazz, 0);
    }


    public <T> List<T> getList(String key, Class<T> clazz) {
        return getList(key, clazz, 0);
    }

    public <T> List<T> getList(String key, Class<T> clazz, int dbIndex) {
        setDbIndex(dbIndex);
        String value = valueOperations.get(key);
        return JSONArray.parseArray(value,clazz);
    }


    /**
     * 获取值-字符串,指定数据库索引,设置过期时间
     *
     * @param key     键
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @param expire  过期时间 单位：秒
     * @return
     */
    public String get(String key, Integer dbIndex, long expire) {
        setDbIndex(dbIndex);
        String value = valueOperations.get(key);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value;
    }

    /**
     * 取值-字符串,指定数据库索引
     *
     * @param key     键
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @return
     */
    public String get(String key, Integer dbIndex) {
        return get(key, dbIndex, NOT_EXPIRE);
    }

    /**
     * 取值-字符串
     *
     * @param key 键
     * @return
     */
    public String get(String key) {
        return get(key, 0, NOT_EXPIRE);
    }

    /**
     * 删除 指定数据库索引
     *
     * @param key     键
     * @param dbIndex 数据库索引 范围 0-15 默认0
     */
    public Boolean delete(String key, Integer dbIndex) {
        setDbIndex(dbIndex);
        return redisTemplate.delete(key);
    }

    /**
     * 删除
     *
     * @param key 键
     */
    public Boolean delete(String key) {
        return delete(key, 0);
    }

    /**
     * 设置过期时间 ,指定数据库索引
     *
     * @param key     键
     * @param dbIndex 数据库索引 范围 0-15 默认0
     * @param expire  过期时间 单位：秒
     */
    public void expire(String key, Integer dbIndex, int expire) {
        setDbIndex(dbIndex);
        if (expire != NOT_EXPIRE) {
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    /**
     * 设置过期时间
     *
     * @param key    键
     * @param expire 过期时间 单位：秒
     */
    public void expire(String key, int expire) {
        expire(key, 0, expire);
    }



    /**
     * 设置数据库索引
     *
     * @param dbIndex
     */
    private void setDbIndex(Integer dbIndex) {
        if (dbIndex == null || dbIndex > 15 || dbIndex < 0) {
            dbIndex = 0;
        }

//        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
//                .build();
        LettuceConnectionFactory lettuceConnectionFactory = (LettuceConnectionFactory) redisTemplate
                .getConnectionFactory();
        lettuceConnectionFactory.setDatabase(dbIndex);
        lettuceConnectionFactory.afterPropertiesSet();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        lettuceConnectionFactory.resetConnection();
    }


    //订单编号自动生成(不重复)
    public String generateOrderNo() {
        // 获取当前日期（格式：yyyyMMdd）
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 生成 Redis key
        String redisKey = ORDER_KEY_PREFIX + date;

        // Redis 自增，获取当日订单编号
        Long increment = redisTemplate.opsForValue().increment(redisKey);

        // 设置过期时间（保证第二天重新开始编号）
        if (increment == 1) {
            redisTemplate.expire(redisKey, java.time.Duration.ofDays(1));
        }

        // 生成订单编号（格式：20250311ORD000001）
        return date + BUSINESS_PREFIX + String.format("%06d", increment);
    }


}